home *** CD-ROM | disk | FTP | other *** search
- /*
- File: IncrSeq.java
-
- Originally written by Doug Lea and released into the public domain.
- Thanks for the assistance and support of Sun Microsystems Labs, Agorics
- Inc, Loral, and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 24Sep95 dl@cs.oswego.edu Create from collections.java working file
- 13Oct95 dl Changed to use accessOnly
-
- */
-
- package collections;
-
- import java.util.Enumeration;
- import java.util.NoSuchElementException;
-
- /**
- *
- * Implementation of Immutable Seq
- * @author Doug Lea
- * @version 0.93
- *
- * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>.
- **/
-
- public final class IncrSeq extends IncrImpl implements Seq {
-
- private int indexArg_;
- /**
- * Make a new pure Seq using the default underlying Seq implementation
- **/
- public IncrSeq() { this(DefaultImplementations.seq()); }
-
- /**
- * Make a pure seq managing the given updatable seq s.
- * Warning: Do not modify s during the the lifetime of the constructed pure seq!
- **/
- public IncrSeq(UpdatableSeq s) { super(s); indexArg_ = 0; }
-
- /**
- * Make a copy. Uses lazy update.
- **/
- protected Object clone() throws CloneNotSupportedException {
- undelta();
- IncrSeq s = new IncrSeq((UpdatableSeq)(updatable_));
- nextVersion_ = s;
- updatable_ = null;
- op_ = NO_EDIT;
- return s;
- }
-
- /**
- * Implements collections.Seq.at.
- * @see collections.Seq#at
- **/
- public synchronized Object at(int index)
- throws NoSuchElementException {
- return ((UpdatableSeq)(accessOnly())).at(index);
- }
-
- /**
- * Implements collections.Seq.first.
- * @see collections.Seq#first
- **/
- public synchronized Object first()
- throws NoSuchElementException {
- return ((UpdatableSeq)(accessOnly())).first();
- }
-
- /**
- * Implements collections.Seq.last.
- * @see collections.Seq#last
- **/
- public synchronized Object last()
- throws NoSuchElementException {
- return ((UpdatableSeq)(accessOnly())).last();
- }
-
- /**
- * Implements collections.Seq.firstIndexOf.
- * @see collections.Seq#firstIndexOf
- **/
- public synchronized int firstIndexOf(Object element, int startingIndex) {
- return ((UpdatableSeq)(accessOnly())).firstIndexOf(element, startingIndex);
- }
-
- /**
- * Implements collections.Seq.firstIndexOf.
- * @see collections.Seq#firstIndexOf
- **/
- public synchronized int firstIndexOf(Object element) {
- return ((UpdatableSeq)(accessOnly())).firstIndexOf(element);
- }
-
- /**
- * Implements collections.Seq.lastIndexOf.
- * @see collections.Seq#lastIndexOf
- **/
- public synchronized int lastIndexOf(Object element, int startingIndex) {
- return ((UpdatableSeq)(accessOnly())).lastIndexOf(element, startingIndex);
- }
-
- /**
- * Implements collections.Seq.lastIndexOf.
- * @see collections.Seq#lastIndexOf
- **/
- public synchronized int lastIndexOf(Object element) {
- return ((UpdatableSeq)(accessOnly())).lastIndexOf(element);
- }
-
- /**
- * Implements collections.Seq.subseq.
- * Makes a full new Seq, not a lazy update.
- * @see collections.Seq#subseq
- **/
- public synchronized /* IncrSeq */ Seq subseq(int index, int length)
- throws NoSuchElementException {
- return new IncrSeq(((UpdatableSeq)(((UpdatableSeq)accessOnly()).subseq(index, length))));
- }
-
-
- /**
- * Implements collections.Collection.removingOneOf
- * @see collections.Collection#removingOneOf
- **/
- public synchronized /* IncrSeq */ Collection removingOneOf(Object element) {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- int idx = u.firstIndexOf(element);
- if (idx < 0)
- return this;
- else {
- try {
- u.removeAt(idx);
- }
- catch (NoSuchElementException ex) {} // can't happen
- IncrSeq s = new IncrSeq(u);
- nextVersion_ = s;
- updatable_ = null;
- firstObjectArg_ = element;
- indexArg_ = idx;
- op_ = ADD_EDIT;
- return s;
- }
- }
-
- /**
- * Implements collections.Collection.excluding.
- * If more than one occurrence of element exists, it makes
- * a full, non-lazy copy.
- * @see collections.Collection#excluding
- **/
- public synchronized /* IncrSeq */ Collection excluding(Object element) {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- int occ = u.occurrencesOf(element);
- if (occ == 0)
- return this;
- else if (occ == 1)
- return this.removingOneOf(element);
- else {
- UpdatableSeq c = (UpdatableSeq)(u.duplicate());
- c.exclude(element);
- return new IncrSeq(c);
- }
- }
-
-
- /**
- * Implements collections.Collection.replacingOneOf
- * @see collections.Collection#replacingOneOf
- **/
- public synchronized /* IncrSeq */ Collection replacingOneOf(Object oldElement,
- Object newElement)
- throws IllegalElementException {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- int idx = u.firstIndexOf(oldElement);
- if (idx < 0)
- return this;
- else {
- try {
- u.replaceAt(idx, newElement);
- }
- catch (NoSuchElementException ex) {} // can't happen
- IncrSeq s = new IncrSeq(u);
- nextVersion_ = s;
- updatable_ = null;
- firstObjectArg_ = oldElement;
- op_ = REPLACE_EDIT;
- indexArg_ = idx;
- return s;
- }
- }
-
- /**
- * Implements collections.Collection.replacingAllOf.
- * If more than one occurrence of element exists, it makes
- * a full, non-lazy copy.
- * @see collections.Collection#replacingAllOf
- **/
- public synchronized /* IncrSeq */ Collection replacingAllOf(Object oldElement,
- Object newElement)
- throws IllegalElementException {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- int oldocc = u.occurrencesOf(oldElement);
- if (oldocc == 0)
- return this;
- else if (oldocc == 1)
- return this.replacingOneOf(oldElement, newElement);
- else {
- UpdatableSeq c = (UpdatableSeq)(u.duplicate());
- c.replaceAllOf(oldElement, newElement);
- return new IncrSeq(c);
- }
- }
-
-
-
- /**
- * Implements collections.Seq.insertingAt.
- * @see collections.Seq#insertingAt
- **/
- public synchronized /* IncrSeq */ Seq insertingAt(int index, Object element)
- throws IllegalElementException, NoSuchElementException {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- u.insertAt(index, element);
- IncrSeq s = new IncrSeq(u);
- nextVersion_ = s;
- updatable_ = null;
- indexArg_ = index;
- op_ = REMOVE_EDIT;
- return s;
- }
-
- /**
- * Implements collections.Seq.removingAt.
- * @see collections.Seq#removingAt
- **/
- public synchronized /* IncrSeq */ Seq removingAt(int index)
- throws NoSuchElementException {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- Object element = u.at(index);
- u.removeAt(index);
- IncrSeq s = new IncrSeq(u);
- nextVersion_ = s;
- updatable_ = null;
- indexArg_ = index;
- firstObjectArg_ = element;
- op_ = ADD_EDIT;
- return s;
- }
-
- /**
- * Implements collections.Seq.replacingAt
- * @see collections.Seq#replacingAt
- **/
- public synchronized /* IncrSeq */ Seq replacingAt(int index, Object element)
- throws IllegalElementException, NoSuchElementException {
- undelta();
- UpdatableSeq u = (UpdatableSeq)updatable_;
- Object oldElement = u.at(index);
- if (oldElement.equals(element))
- return this;
- else {
- u.replaceAt(index, element);
- IncrSeq s = new IncrSeq(u);
- nextVersion_ = s;
- updatable_ = null;
- indexArg_ = index;
- firstObjectArg_ = oldElement;
- op_ = REPLACE_EDIT;
- return s;
- }
- }
-
-
- /**
- * Perform updates within an edit chain
- **/
- protected synchronized UpdatableCollection doEdit(UpdatableCollection c) {
- UpdatableSeq u = (UpdatableSeq)c;
- try {
- if (op_ == ADD_EDIT)
- u.insertAt(indexArg_, firstObjectArg_);
- else if (op_ == REMOVE_EDIT)
- u.removeAt(indexArg_);
- else if (op_ == REPLACE_EDIT)
- u.replaceAt(indexArg_, firstObjectArg_);
- }
- catch (IllegalElementException ex) {} // we've screened for all possible
- catch (NoSuchElementException ex) {}
- return u;
- }
-
-
- }
-
-